﻿using System;
using System.Windows.Input;
using Ninject.Core.Parameters;
using TestBat.ISettings;
using TestBat.ISettings.Database;
using TestBat.IViewModels.Windows;
using TestBat.ServiceLocator;
using TestBat.ViewModels.Base;
using TestBat.ViewModels.Base.Commands;

namespace TestBat.ViewModels.Windows
{
    public class SetupWizardWindowViewModel : DialogViewModelContainer, ISetupWizardWindowViewModel
    {
        public SetupWizardWindowViewModel(IDatabaseConnectionTester connectionTester)
        {
            this.settingsPersister = DefaultServiceLocator.Get<IExeSettingsPersister>(With.Parameters.Variable("exe", true));
            this.connectionTester = connectionTester;
            DBConnectionTestSuccessful = null;

            this.settings = settingsPersister.Load();
        }

        public event EventHandler CloseEvent;

        public string DBName
        {
            get
            {
                return settings.DBName;
            }
            set
            {
                settings.DBName = value;
                NotifyPropertyChanged(() => DBName);
                DBConnectionTestSuccessful = null;
            }
        }

        public string DBAddress
        {
            get
            {
                return settings.DBAddress;
            }
            set
            {
                settings.DBAddress = value;
                NotifyPropertyChanged(() => DBAddress);
                DBConnectionTestSuccessful = null;
            }
        }

        public string DBUsername
        {
            get
            {
                return settings.DBUsername;
            }
            set
            {
                settings.DBUsername = value;
                NotifyPropertyChanged(() => DBUsername);
                DBConnectionTestSuccessful = null;
            }
        }

        public string DBPassword
        {
            get
            {
                return settings.DBPassword;
            }
            set
            {
                settings.DBPassword = value;
                NotifyPropertyChanged(() => DBPassword);
                DBConnectionTestSuccessful = null;
            }
        }

        public string DBType
        {
            get
            {
                return settings.DBType;
            }
            set
            {
                settings.DBType = value;
                NotifyPropertyChanged(() => DBType);
                DBConnectionTestSuccessful = null;
            }
        }

        private bool? DBConnectionTestSuccessful
        {
            get
            {
                return DBConnectionSuccessful;
            }
            set
            {
                DBConnectionSuccessful = value;
                NotifyPropertyChanged(() => DBConnectionTestSuccessful);
                NotifyPropertyChanged(() => ShowDBConnectionFailureMessage);
                NotifyPropertyChanged(() => ShowDBConnectionSuccessMessage);
            }
        }

        public bool ShowDBConnectionFailureMessage
        {
            get
            {
                return DBConnectionSuccessful.HasValue && !DBConnectionSuccessful.Value;
            }
        }

        public bool ShowDBConnectionSuccessMessage
        {
            get
            {
                return DBConnectionSuccessful.HasValue && DBConnectionSuccessful.Value;
            }
        }

        public ICommand FinishCommand
        {
            get
            {
                return new RelayCommand(c =>
                    {
                        // set first start to false
                        settings.FirstStart = false;

                        // save settings
                        settingsPersister.Save(settings);

                        if (CloseEvent != null)
                            CloseEvent(this, null);
                    });
            }
        }

        public ICommand TestDBConnectionCommand
        {
            get
            {
                return new RelayCommand(c =>
                {
                    IDatabaseTypeConverter typeConverter = DefaultServiceLocator.Get<IDatabaseTypeConverter>();
                    DBConnectionSuccessful = connectionTester.Test(typeConverter.Convert(DBType), DBName, DBAddress, DBUsername, DBPassword);
                    NotifyPropertyChanged(() => ShowDBConnectionFailureMessage);
                    NotifyPropertyChanged(() => ShowDBConnectionSuccessMessage);
                });
            }
        }

        private IExeSettingsPersister settingsPersister;
        private IExeSettings settings;
        private readonly IDatabaseConnectionTester connectionTester;
        private bool? DBConnectionSuccessful;
    }
}
